package com.zyh.scs.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyh.scs.admin.api.constant.RechargeTypeEnum;
import com.zyh.scs.admin.api.entity.UserBill;
import com.zyh.scs.admin.api.entity.UserTransaction;
import com.zyh.scs.admin.api.utils.UserTypeToNameUtil;
import com.zyh.scs.admin.api.vo.BillExcelCardVO;
import com.zyh.scs.admin.api.vo.BillExcelCashVO;
import com.zyh.scs.admin.api.vo.BillExcelEntityVO;
import com.zyh.scs.admin.mapper.UserBillMapper;
import com.zyh.scs.admin.mapper.UserTransactionMapper;
import com.zyh.scs.admin.service.UserBillService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author hwh
 * @ClassName: 账单管理api接口实现类$
 * @Description: $
 * @Date $
 * @Version 1.0
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserBillServiceImpl extends ServiceImpl<UserBillMapper, UserBill> implements UserBillService {

    private final UserBillMapper userBillMapper;

    private final UserTransactionMapper userTransactionMapper;

    @Override
    public IPage getBillPage(Page page, String beginTime, String endTime, Integer billType) {
        Page<UserBill> userBillPage = new Page<>(page.getCurrent(), page.getSize());
        LambdaQueryWrapper<UserBill> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBill::getBillType, billType)
                .ge(StrUtil.isNotBlank(beginTime), UserBill::getBillTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), UserBill::getBillTime, endTime)
                .orderByDesc(UserBill::getCreateTime);
        return this.page(userBillPage, queryWrapper);
    }

    @Override
    public String getDownLoadExcel(Long userBillId) {
        UserBill userBill = userBillMapper.selectById(userBillId);
        return userBill.getFilePath();
    }

    @Override
    public IPage getBillInfo(Page page, String rechargeStream, String thirdRechargeStream, String beginTime, String endTime, String guid, Integer billType) {
        Page<UserTransaction> userTransactionPage = new Page<>(page.getCurrent(), page.getSize());
        LambdaQueryWrapper<UserTransaction> queryWrapper = getUserTransactionLambdaQueryWrapper(rechargeStream, thirdRechargeStream, beginTime, endTime, guid, billType, 2);
        return userTransactionMapper.selectPage(userTransactionPage, queryWrapper);
    }

    @Override
    public IPage<UserTransaction> getBillAllInfo(Page page, String rechargeStream, String thirdRechargeStream, String beginTime, String endTime, String guid) {
        Page<UserTransaction> userTransactionPage = new Page<>(page.getCurrent(), page.getSize());
        LambdaQueryWrapper<UserTransaction> queryWrapper = getUserTransactionLambdaQueryWrapper(rechargeStream, thirdRechargeStream, beginTime, endTime, guid, null, 2);
        return userTransactionMapper.selectPage(userTransactionPage, queryWrapper);
    }

    private static @NotNull LambdaQueryWrapper<UserTransaction> getUserTransactionLambdaQueryWrapper(String rechargeStream, String thirdRechargeStream, String beginTime, String endTime, String guid, Integer billType, Integer isExcel) {
        if (StrUtil.isBlank(beginTime) && StrUtil.isBlank(endTime) && StrUtil.isBlank(rechargeStream) && StrUtil.isBlank(thirdRechargeStream)) {
            beginTime = LocalDate.now().plusDays(-3).toString();
        }

        LambdaQueryWrapper<UserTransaction> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserTransaction::getGuid, guid)
                .eq(billType != null, UserTransaction::getAccountType, billType)
                .eq(StrUtil.isNotBlank(rechargeStream), UserTransaction::getRechargeStream, rechargeStream)
                .eq(StrUtil.isNotBlank(thirdRechargeStream), UserTransaction::getThirdRechargeStream, thirdRechargeStream)
                .ge(StrUtil.isNotBlank(beginTime), UserTransaction::getTransactionTime, UserTypeToNameUtil.stringToLocalBeginTime(beginTime))
                .le(StrUtil.isNotBlank(endTime), UserTransaction::getTransactionTime, UserTypeToNameUtil.stringToLocalEndTime(endTime))
                .orderByDesc(UserTransaction::getTransactionTime);

        if (isExcel == 1) {
                queryWrapper.last(" limit 100000");
        }
        return queryWrapper;
    }


    public List<BillExcelEntityVO> getBillInfoExcel(String rechargeStream, String thirdRechargeStream, String beginTime, String endTime, String guid, Integer billType) {
        if (billType == 4) {
            billType = null;
        }
        LambdaQueryWrapper<UserTransaction> queryWrapper = getUserTransactionLambdaQueryWrapper(rechargeStream, thirdRechargeStream, beginTime, endTime, guid, billType, 1);
        List<UserTransaction> userTransactionList = userTransactionMapper.selectList(queryWrapper);
        List<BillExcelEntityVO> billExcelVOList = new ArrayList<>();
        AtomicInteger index = new AtomicInteger(1);
        userTransactionList.forEach(a -> {
            BillExcelEntityVO billExcelVO = new BillExcelEntityVO();
            BeanUtil.copyProperties(a, billExcelVO);
            if (a.getUserType() != null) {
                billExcelVO.setUserTypeName(UserTypeToNameUtil.getUserType(a.getUserType()));
            }
            if (a.getTransactionType() != null) {
                billExcelVO.setTransactionType(UserTypeToNameUtil.getTransactionType(a.getTransactionType()));
            }
            if (a.getAccountType().equals("1")) {
                billExcelVO.setRechargeTypeName(RechargeTypeEnum.MEAL_ACCOUNT.getDesc());
            } else {
                billExcelVO.setRechargeTypeName(RechargeTypeEnum.CASH_ACCOUNT.getDesc());
            }
            billExcelVO.setIndex(index.getAndIncrement());
            billExcelVOList.add(billExcelVO);
        });
        return billExcelVOList;
    }

    @Override
    public List<BillExcelCardVO> getCardExcel(String rechargeStream, String thirdRechargeStream, String beginTime, String endTime, String guid) {
        LambdaQueryWrapper<UserTransaction> queryWrapper = getUserTransactionLambdaQueryWrapper(rechargeStream, thirdRechargeStream, beginTime, endTime, guid, 1, 1);
        List<UserTransaction> userTransactionList = userTransactionMapper.selectList(queryWrapper);
        List<BillExcelCardVO> billExcelVOList = new ArrayList<>();
        AtomicInteger index = new AtomicInteger(1);
        userTransactionList.forEach(a -> {
            BillExcelCardVO billExcelVO = new BillExcelCardVO();
            BeanUtil.copyProperties(a, billExcelVO);
            if (a.getUserType() != null) {
                billExcelVO.setUserTypeName(UserTypeToNameUtil.getUserType(a.getUserType()));
            }
            if (a.getTransactionType() != null) {
                billExcelVO.setTransactionType(UserTypeToNameUtil.getTransactionType(a.getTransactionType()));
            }
            billExcelVO.setIndex(index.getAndIncrement());
            billExcelVOList.add(billExcelVO);
        });
        return billExcelVOList;
    }

    @Override
    public List<BillExcelCashVO> getCashExcel(String rechargeStream, String thirdRechargeStream, String beginTime, String endTime, String guid) {
        LambdaQueryWrapper<UserTransaction> queryWrapper = getUserTransactionLambdaQueryWrapper(rechargeStream, thirdRechargeStream, beginTime, endTime, guid, 2, 1);
        List<UserTransaction> userTransactionList = userTransactionMapper.selectList(queryWrapper);
        List<BillExcelCashVO> billExcelVOList = new ArrayList<>();
        AtomicInteger index = new AtomicInteger(1);
        userTransactionList.forEach(a -> {
            BillExcelCashVO billExcelVO = new BillExcelCashVO();
            BeanUtil.copyProperties(a, billExcelVO);
            if (a.getUserType() != null) {
                billExcelVO.setUserTypeName(UserTypeToNameUtil.getUserType(a.getUserType()));
            }
            if (a.getTransactionType() != null) {
                billExcelVO.setTransactionType(UserTypeToNameUtil.getTransactionType(a.getTransactionType()));
            }
            billExcelVO.setIndex(index.getAndIncrement());
            billExcelVOList.add(billExcelVO);
        });
        return billExcelVOList;
    }
}
